﻿using KBEngine;
using System;
using System.Collections;
using System.Collections.Generic;

namespace KBEngine
{
    /// <summary>
    /// 自定义的逻辑事件管理器，方便统一的管理和分发
    /// fireOut是在unity的主线程下分发,所以在unity中的操作是线程安全的
    /// </summary>
    internal sealed class LogicEvents
    {
        public static bool Check()
        {
            List<string> events = GetEngineEventNames();
            Type[] chlidTypes = GetChildTypes(typeof(EventRouter));
            foreach (var item in chlidTypes)
            {
                var eventRouter = (EventRouter)Activator.CreateInstance(item);
                if (!eventRouter.Check(events))
                    return false;
            }
            return true;
        }
        /// <summary>
        /// 获取所有Engine内置事件名,用于重名检测
        /// </summary>
        /// <returns></returns>
        public static List<string> GetEngineEventNames()
        {
            List<string> result = new List<string>();
            System.Type t = typeof(KBEngine.EventOutTypes);
            System.Reflection.FieldInfo[] infos = t.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
            foreach (var info in infos)
            {
                string v = (string)info.GetValue(null);
                //DebugMsgMgr.Instance.Log(string.Format("Add Engine EventNames:{0}", v));
                result.Add(v);
            }

            t = typeof(KBEngine.EventInTypes);
            infos = t.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
            foreach (var info in infos)
            {
                string v = (string)info.GetValue(null);
                //DebugMsgMgr.Instance.Log(string.Format("Add Engine EventNames:{0}", v));
                result.Add(v);
            }
            return result;
        }

        /// <summary>
        /// 通过反射获取继承该类的所有子类
        /// </summary>
        /// <param name="parentType">父类的type</param>
        /// <returns>所有子类</returns>
        public static Type[] GetChildTypes(Type parentType)
        {
            List<Type> lstType = new List<Type>();
            System.Reflection.Assembly assem = System.Reflection.Assembly.GetAssembly(parentType);
            foreach (Type tChild in assem.GetTypes())
            {
                if (tChild.IsInterface)
                    continue;

                if (parentType.IsInterface)
                {
                    Type[] ins = tChild.GetInterfaces();
                    if (Array.Find(ins, (x) => x == parentType) != null)
                        lstType.Add(tChild);
                }
                else
                {
                    if (tChild.BaseType == parentType)
                    {
                        lstType.Add(tChild);
                    }
                }
            }
            return lstType.ToArray();
        }

    }
}